export const getInputs = () => [[[197, 130, 1]], [[235, 140, 4]], [[250, 145, 145, 145, 145]]];

/**
 * **[393. UTF-8 编码验证](https://leetcode.cn/problems/utf-8-validation/)**
 *
 * 给定一个表示数据的整数数组 `data` ，返回它是否为有效的 **UTF-8** 编码。
 *
 * **UTF-8** 中的一个字符可能的长度为 **1 到 4 字节**，遵循以下的规则：
 *
 * 对于 **1 字节** 的字符，字节的第一位设为 0 ，后面 7 位为这个符号的 unicode 码。
 *
 * 对于 **n 字节** 的字符 (n > 1)，第一个字节的前 n 位都设为1，第 n+1 位设为 0 ，后面字节的前两位一律设为 10 。剩下的没有提及的二进制位，全部为这个符号的 unicode 码。
 *
 * 这是 UTF-8 编码的工作方式：
 *
 * | Number of Bytes | UTF-8 octet sequence (binary) |
 * | --- | --- |
 * | 1 | 0xxxxxxx |
 * | 2 | 110xxxxx 10xxxxxx |
 * | 3 | 1110xxxx 10xxxxxx 10xxxxxx |
 * | 4 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
 *
 * `x` 表示二进制形式的一位，可以是 `0` 或 `1`。
 *
 * **注意：**输入是整数数组。只有每个整数的 **最低 8 个有效位** 用来存储数据。这意味着每个整数只表示 1 字节的数据。
 *
 * @param data
 * @returns
 */
export default function (data: number[]): boolean {
	let index = 0;
	const len = data.length;
	while (index < len) {
		let bytes = howMuchByte(data[index++]);

		if (bytes === -1 || bytes + index > len) return false;

		while (bytes-- > 0) {
			if (!is10xxxxxxx(data[index++])) return false;
		}
	}
	return true;
}

const VALUE_100000000 = 1 << 7;
const VALUE_110000000 = (1 << 6) + VALUE_100000000;
const VALUE_111000000 = (1 << 5) + VALUE_110000000;
const VALUE_111100000 = (1 << 4) + VALUE_111000000;
const VALUE_111110000 = (1 << 3) + VALUE_111100000;
// const VALUE_111111000 = (1 << 2) + VALUE_111110000;
// const VALUE_111111100 = (1 << 1) + VALUE_111111000;
// const VALUE_111111110 = VALUE_111111100 + 1;
function howMuchByte(num: number): number {
	if (num < VALUE_100000000) return 0;
	if (num < VALUE_110000000) return -1; // error
	if (num < VALUE_111000000) return 1;
	if (num < VALUE_111100000) return 2;
	if (num < VALUE_111110000) return 3;

	return -1; // 最多 4 个字节 // [250, 145, 145, 145, 145]
	// if (num < VALUE_111111000) return 4;
	// if (num < VALUE_111111100) return 5;
	// if (num < VALUE_111111110) return 6;
	// return 7;
}
function is10xxxxxxx(num: number): boolean {
	return num >= VALUE_100000000 && num < VALUE_110000000;
}
